Skip to content

Add URRobotCfg, and dual-arm composition#331

Merged
yuecideng merged 26 commits into
mainfrom
feat/ur-robot
Jun 30, 2026
Merged

Add URRobotCfg, and dual-arm composition#331
yuecideng merged 26 commits into
mainfrom
feat/ur-robot

Conversation

@yuecideng

@yuecideng yuecideng commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

This PR expands the robot configuration system in three connected parts:

  1. It lifts the unified RobotCfg protocol into the base class so robot configs can build defaults through _build_defaults, round-trip through from_dict/to_dict, and tolerate subclass-specific keys in merge_robot_cfg.
  2. It adds URRobotCfg, a single RobotCfg subclass covering the Universal Robots family (ur3, ur3e, ur5, ur5e, ur10, ur10e) through robot_type.
  3. It adds generic dual-arm composition so any compatible single-arm robot config can be assembled into a two-arm robot via DualArmRobotCfg or build_dual_arm_cfg.

What changed

  • Unified robot protocol in RobotCfg: _build_defaults hook, base serialization flow, _pk_urdf_path support for build_pk_serial_chain, and cfg merge support for subclass keys.
  • Robot conversions to the new protocol: updated dexforce_w1 and cobotmagic, cleaned up robot exports, and aligned the add-robot docs/context/skill around the new pattern.
  • URRobotCfg: one class for six UR variants, including per-variant URDF selection, joint-name casing, control parts, and scale-aware drive defaults.
  • Dual-arm composition: DualArmRobotCfg, build_dual_arm_cfg, and mount resolution utilities to derive a dual manipulator from a single-arm robot cfg, including optional composite dual_arm control parts.
  • UR solver fix: URSolverCfg now declares class_type = "URSolver", which fixes deserialization/round-trip through config dicts.
  • Tutorial updates: atomic-action tutorial scripts were adjusted to the updated robot/config behavior.

Docs

  • Added docs/source/resources/robot/ur_robot.md.
  • Added docs/source/resources/robot/dual_arm.md.
  • Updated docs/source/resources/robot/index.rst.
  • Updated robot tutorial/context/add-robot skill docs for the unified protocol.
  • Added dual-arm and UR robot images under docs/source/_static/robots/.

Tests

  • Added UR robot config coverage in tests/sim/objects/test_robot_cfg.py.
  • Added dual-arm coverage in tests/sim/objects/test_dual_arm.py, including control parts, solver behavior, round-trip serialization, PK DOF checks, and assembled UR5 joint-name validation.
  • Latest branch commits also include test fixes to keep the suite aligned with the current implementation.

Dependencies

  • No external dependency changes.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (non-breaking change which improves an existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (existing functionality will not work without user modification)
  • Documentation update

Screenshots

N/A.

Checklist

  • I have run the black . command to format the code base.
  • I have made corresponding changes to the documentation.
  • I have added tests that prove my feature works.
  • Dependencies have been updated, if applicable.

yuecideng and others added 13 commits June 26, 2026 00:40
One RobotCfg subclass switchable via robot_type; DH params owned by
URSolverCfg, the robot config owns URDF/control parts/drive props/attrs.
Per-variant max_effort scaled by robot size; UR5's lowercase joint names
handled explicitly. Routes build_pk_serial_chain through _pk_urdf_path.

Also fixes URSolverCfg.class_type (inherited "BaseSolver" -> "URSolver")
so the solver can be deserialized from a dict (enables cfg round-trip).

Co-Authored-By: Claude <noreply@anthropic.com>
Adds docs/source/resources/robot/ur_robot.md and registers it in
resources/robot/index.rst. Adds a __main__ block to ur_robot.py that
adds the robot to a sim and checks the to_dict round-trip.

Co-Authored-By: Claude <noreply@anthropic.com>
@yuecideng yuecideng added enhancement New feature or request robot Module related to robot labels Jun 26, 2026
@yuecideng yuecideng requested a review from matafela June 26, 2026 03:47
Comment thread embodichain/lab/sim/robots/ur_robot.py Outdated
yuecideng and others added 7 commits June 27, 2026 17:21
…ingle-arm robot

Generic build_dual_arm_cfg engine + DualArmRobotCfg wrapper that derives a
two-arm config (left/right/dual parts, per-arm solver, mirrored drive props)
from any single-arm RobotCfg following the "arm" convention — today UR,
future Franka via a one-line registry entry. Dict/YAML constructible.

Co-Authored-By: Claude <noreply@anthropic.com>
…m robot

build_dual_arm_cfg engine + DualArmRobotCfg wrapper derive a two-arm config
(left/right/dual control_parts, per-arm solver_cfg, mirrored drive_pros) from
any single-arm RobotCfg following the "arm" convention. Today the UR family;
future Franka needs only a one-line registry entry — no dual class, no mixin.

Two orphan arms mount on a shared base_link via existing URDFCfg assembly;
preset+override mounts (side_by_side / facing_inward); dict/YAML constructible
and round-trippable. Reuses URSolverCfg arm-local FK/IK (link names stay
unprefixed since URSolverCfg pins urdf_path in __post_init__).

Tests: 16 new (resolve_mounts, prefixed_name, engine, from_dict/round-trip,
PK-DOF drift guard, real dual UR5 URDF assembly name match). No regressions
(44 passed incl. existing robot cfg tests).

Co-Authored-By: Claude <noreply@anthropic.com>
Base automatically changed from feat/robot-unified-protocol to main June 29, 2026 03:22
Copilot AI review requested due to automatic review settings June 29, 2026 06:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class robot configuration support for the Universal Robots UR family via a single URRobotCfg (variant-selected by robot_type), plus a generic dual-arm composition path (DualArmRobotCfg) built on multi-component URDF assembly. The PR also extends URDF assembly naming controls (introducing an "original" casing mode), fixes URSolverCfg deserialization, updates atomic-action tutorials to reuse a shared UR5+gripper config helper, and adds docs + tests around the new robot configs.

Changes:

  • Introduce URRobotCfg (UR3/UR3e/UR5/UR5e/UR10/UR10e) and add UR-family tests (from_dict, round-trip, PK DOF drift guard, effort scaling, unknown type).
  • Add DualArmRobotCfg + builder utilities (resolve_mounts, build_dual_arm_cfg) and a dedicated test suite verifying naming/assembly invariants.
  • Expand URDF assembly name normalization to support "original" casing and merge urdf_cfg.name_case through merge_robot_cfg; update docs/tutorial scripts accordingly.

Reviewed changes

Copilot reviewed 20 out of 29 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/sim/objects/test_robot_cfg.py Adds URRobotCfg unit tests (construction, round-trip, PK drift-guard, effort scaling, error case).
tests/sim/objects/test_dual_arm.py New comprehensive tests for dual-arm composition (mount presets, derived names, URDF assembly integration).
scripts/tutorials/atomic_action/tutorial_utils.py Adds create_ur5_gripper_robot_cfg helper and constants; tutorials reuse it.
scripts/tutorials/atomic_action/place.py Switches UR5 robot creation to shared helper, removes duplicated config code.
scripts/tutorials/atomic_action/pickup.py Switches UR5 robot creation to shared helper, removes duplicated config code.
scripts/tutorials/atomic_action/move_joints.py Switches UR5 robot creation to shared helper, removes duplicated config code.
scripts/tutorials/atomic_action/move_held_object.py Switches UR5 robot creation to shared helper, cleans up imports/ordering.
scripts/tutorials/atomic_action/move_end_effector.py Switches UR5 robot creation to shared helper, removes duplicated config code.
embodichain/toolkits/urdf_assembly/name_normalizer.py Adds "original" normalization mode alongside legacy "none".
embodichain/toolkits/urdf_assembly/connection.py Updates docstring to mention "original" mode support.
embodichain/toolkits/urdf_assembly/component.py Updates docstring to mention "original" mode support.
embodichain/lab/sim/utility/cfg_utils.py Merges urdf_cfg.name_case when applying overrides in merge_robot_cfg.
embodichain/lab/sim/solvers/ur_solver.py Fixes URSolverCfg deserialization by setting class_type = "URSolver".
embodichain/lab/sim/robots/ur_robot.py New UR-family RobotCfg subclass with variant-driven URDF + defaults + PK chain builder.
embodichain/lab/sim/robots/dual_arm.py New dual-arm composition engine + wrapper config + PK chain builder.
embodichain/lab/sim/robots/__init__.py Exports URRobotCfg, DualArmRobotCfg, and build_dual_arm_cfg.
embodichain/lab/sim/cfg.py Changes URDFCfg name_case defaults/documentation for casing policy during assembly.
docs/source/resources/robot/ur_robot.md New documentation page for UR family robot config.
docs/source/resources/robot/dual_arm.md New documentation page for dual-arm composition API and presets.
docs/source/resources/robot/index.rst Registers UR family and dual-arm docs pages in the robots index.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1056 to +1061
"""Case normalization policy applied to joint/link names during URDF assembly.

Supported values per key are ``"upper"``, ``"lower"`` or ``"original"``
(legacy alias ``"none"``). The default upper-cases joints and lower-cases
links. Set ``{"joint": "original"}`` to preserve the source URDF casing.
"""
Comment on lines 24 to +28
import torch

from embodichain.data import get_data_path
from embodichain.lab.sim import SimulationManager
from embodichain.lab.sim.cfg import MarkerCfg
from embodichain.lab.sim.cfg import MarkerCfg, RobotCfg
Comment on lines +130 to +138
.. attention::
:class:`~embodichain.lab.sim.cfg.URDFCfg` defaults to upper-casing joint
names during multi-component assembly. The override dict passed to
:meth:`URRobotCfg.from_dict` sets
``urdf_cfg.name_case = {"joint": "lower", "link": "lower"}`` so the
assembled robot keeps the source URDF's lowercase joint names
(``joint1``..``joint6`` and ``gripper_finger1_joint_1``), matching the
control parts produced by
:class:`~embodichain.lab.sim.robots.ur_robot.URRobotCfg`.
Comment on lines +22 to +27
from embodichain.lab.sim.cfg import (
RobotCfg,
URDFCfg,
JointDrivePropertiesCfg,
RigidBodyAttributesCfg,
)
robot_type: str = "ur10"

@classmethod
def from_dict(cls, init_dict):
Comment on lines +271 to +274
Scalar fields apply to all joints uniformly and are copied verbatim. A
regex->value dict (per-joint-index drive) is mirrored by uppercasing each
pattern and emitting ``LEFT_`` / ``RIGHT_`` variants, matching the
assembled (prefixed) joint names.
@yuecideng yuecideng changed the title Add URRobotCfg: UR family (ur3/3e/5/5e/10/10e) Add RobotCfg protocol, URRobotCfg, and dual-arm composition Jun 29, 2026
@yuecideng yuecideng changed the title Add RobotCfg protocol, URRobotCfg, and dual-arm composition Add URRobotCfg, and dual-arm composition Jun 29, 2026
@matafela matafela self-requested a review June 29, 2026 08:47
Copilot AI review requested due to automatic review settings June 29, 2026 13:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@yuecideng yuecideng merged commit b2d6633 into main Jun 30, 2026
5 checks passed
@yuecideng yuecideng deleted the feat/ur-robot branch June 30, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request robot Module related to robot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants